package com.cfjjc.gz.common.action;

import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.cfjjc.gz.common.exception.OTSException;
import com.cfjjc.gz.common.util.paged.PagedList;
  
/**
 * 自定义的具有分页功能的action基类,继承自BaseAction
 * 
 */
public abstract class PagedAction extends BaseAction {

	private static final long serialVersionUID = -6622868068386840491L;

	// 查询结果集,分页
	protected PagedList pagedRecords = new PagedList();

	/**
	 * 以下属性用于序列化成json格式的数据。名称不能改。如果要改，客户端页面对应的地方也要改； 或通过@JSON来指定序列化的名字
	 */

	// 要转至页面,默认为零
	protected int page = 0;

	// 页面大小 － 每个页面显示的记录数
	protected int pageSize = PagedList.DEFAULT_PAGE_SIZE;

	// 是否为第一次查询,默认为真
	protected boolean firstQuery = true;

	/**
	 * 用于标识虽然此次查询是一次新的查询,但是查询条件和上次一样 <br>
	 * 说明:在应用中我们可能会遇到如下情况,在一个完整的页面中,包括查询条件,功能操作按钮,以及查询结果显示列表.<br>
	 * 其中,查询结果,功能操作（如新增,修改)等均在完整页面中的ifame中进行<br>
	 * 比如我们现在进行新增缴款书录入的操作,完了以后应该刷新结果列表以便显示出最新的记录情况.
	 * 此时分页查询时应该设置firstQuery=true的标志,但是由于受到整个页面中已经设定的查询条件的限制,查询时就又需要知道
	 * 这之前查询时依据的查询条件,此时便需要设置以下useOldParam这个标志为true
	 */
	protected boolean useOldParam = false;

	public PagedAction() {
		super();
	}

	/**
	 * 根据当前的参数状况，准备数据分页对象，并设置对象要显示哪一页的数据。 <br>
	 * 如果是第一次请求(firstQuery=y)，会创建一个对象，存放到session中。<br>
	 * 如果是后继请求，则从session中取出对象 。<br>
	 * 如果返回null，则表示不是第一次查询，但session中又没有改对象，或者对象的类型不正确。
	 * 
	 * @param queryName
	 *            session中存放的分页查询结果对象的名字
	 * @param param
	 *            查询参数对象
	 * @return 新创建或从session获得的分页对象
	 */
	protected void preparePagedList(String queryName, Object param)
			throws OTSException {
		preparePagedList(queryName, param, PagedList.NAME);
	}

	protected void preparePagedList(String queryName, Object param,
			String session_name) throws OTSException {
		// 得到Session对象
		ActionContext ctx = ActionContext.getContext();
		Map session = ctx.getSession();

		if (firstQuery == true) {
			if (logger.isDebugEnabled()) {
				logger.debug("新的查询");
			}
			pagedRecords = new PagedList();

			// 给对象设置一个查询名称，以示区别
			pagedRecords.setQueryName(queryName);

			// 虽然是一次新的查询,但告知要使用上次的查询条件的情况下
			if (useOldParam == true) {
				PagedList p = (PagedList) session.get(session_name);
				/*
				 * 在这还要确认传入的param对象与以前保存的param对象类型相同
				 */
				if (p.getParam().getClass().getName().equals(
						param.getClass().getName())) {
					pagedRecords.setParam(p.getParam());
					if (logger.isDebugEnabled()) {
						logger.debug("新的查询,但继续沿用上次的查询条件.");
					}
				} else {
					logger.error("新的查询,指明继续沿用上次的查询条件.但上次查询条件参数对象类型["
							+ p.getParam().getClass() + "]与当前param类型["
							+ param.getClass() + "]不一致");

					throw new OTSException("系统发生内部错误,请联系管理员");
				}
			}
			// 否则,就用当前模型对象作为查询参数
			else {
				pagedRecords.setParam(param);
			}

			// 存入session
			session.remove(session_name);
			session.put(session_name, pagedRecords);
		} else {
			pagedRecords = (PagedList) session.get(session_name);
			if (null != pagedRecords
					&& !queryName.equalsIgnoreCase(pagedRecords.getQueryName())) {

				//说明：多tab页时，后显示页面的列表会冲掉之前tab页存在session中的列表，若查询名不一致的话，视为第一次查询。
				pagedRecords = new PagedList();
				pagedRecords.setQueryName(queryName);
				pagedRecords.setParam(param);
				session.remove(session_name);// 存入session
				session.put(session_name, pagedRecords);
			}
		}
		/**
		 * 设置请求页码
		 */
		if (this.page == 0) {
			this.page = 1;
		}
		if (pagedRecords != null) {
			pagedRecords.setPage(this.page);
			pagedRecords.setPageSize(this.pageSize);
		}
	}

	/**
	 * @param pagedRecords
	 *            The pagedRecords to set.
	 */
	public void setPagedRecords(PagedList pagedRecords) {
		this.pagedRecords = pagedRecords;
	}

	/**
	 * @return Returns the firstQuery.
	 */
	public boolean isFirstQuery() {
		return firstQuery;
	}

	/**
	 * @param firstQuery
	 *            The firstQuery to set.
	 */
	public void setFirstQuery(boolean firstQuery) {
		this.firstQuery = firstQuery;
	}

	/**
	 * @return Returns the useOldParam.
	 */
	public boolean isUseOldParam() {
		return useOldParam;
	}

	/**
	 * @param useOldParam
	 *            The useOldParam to set.
	 */
	public void setUseOldParam(boolean useOldParam) {
		this.useOldParam = useOldParam;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cfjjc.gz.common.action.PagedAction#setPage(int)
	 */
	public void setPage(String page) {
		this.page = Integer.valueOf(page);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cfjjc.gz.common.action.PagedAction#setRows(java.lang.String)
	 */
	public void setRows(String rows) {
		this.pageSize = Integer.valueOf(rows);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cfjjc.gz.common.action.BaseAction#getRows()
	 */
	@Override
	public List<?> getRows() {
		if (pagedRecords == null || pagedRecords.getTotalNum() == -1) {
			return this.rows;
		}
		return pagedRecords.getList();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.cfjjc.gz.common.action.BaseAction#getTotal()
	 */
	@Override
	public Integer getTotal() {
		if (pagedRecords == null || pagedRecords.getTotalNum() == -1) {
			return this.rows.size();
		}
		return pagedRecords.getTotalNum();
	}

	/**
	 * @return 返回pagedRecords
	 */
	public PagedList getPagedRecords() {
		return pagedRecords;
	}
}
